package Submarine;

import java.awt.*;
import java.util.Random;
import javax.swing.ImageIcon;

public abstract class SeaObject {
    public static int LIVE = 0;//活着的
    public static int DEAD = 1;//死了的
    //变量
    protected int state = LIVE;//当前状态
    protected int x, y, width, height;
    protected double speed;
    Random rand = new Random();

    //构造方法

    /**
     * -- 潜艇 --
     */
    public SeaObject(int width, int height) {
        this.width = width;
        this.height = height;
        x = -width;
        y = 150 + rand.nextInt(World.HEIGHT - height - 150 + 1);
        speed = (rand.nextInt(3+(int)(World.times)) + 1) ;
    }

    /**
     * -- 水雷、炸弹、战舰 --
     */
    public SeaObject(int x, int y, double speed, int width, int height) {
        this.x = x;
        this.y = y;
        if (this.speed < this.speed + 2) {
            this.speed = speed * World.times;
        } else {
            this.speed = speed + 2 ;
        }
        this.height = height;
        this.width = width;
    }

    /**
     * -- 发射水雷 --
     */
    public Mine shootMine() {
        if (this instanceof MineSubmarine) {
            return new Mine(this.x + this.width, this.y - 11);
        } else {
            return null;
        }
    }

    public abstract void move();

    /** 画对象需要4个数据：
     * 1.对象的状态(较难)，
     * 2.对象的图片，
     * 3.对象的x坐标，
     * 4.对象y的坐标(后面三个不难)
     *
     * 步骤：
     * 1)因为只有活着的对象才需要画到窗口中，所以需要设计对象的状态(活着还是死了)
     *   每个对象都有状态，意味着状态为共有属性，所以设计在超类里面
     *   状态一般设计为常量，同时再设计state变量表示当前状态
     *     ---在SeaObject中设计LIVE、DEAD常量，state变量表示当前状态
     *   后期需要经常判断对象的状态，每个对象都要判断，意味着判断状态的行为为共有行为，所以设计在SeaObject超类中;
     *   每个对象判断状态的代码都是一样的，所以设计为普通方法
     *     ---在SeaObject中设计isLive()、isDead()判断对象的状态
     * 2)若对象为活着的，则需要画对象，画对象还需要获取对象的图片，每个对象都能得图片，
     *   意味着获取图片行为为共有行为，所以设计在SeaObject超类中;
     *   每个对象获取图片的代码都是不一样的，所以设计为抽象方法
     *     ---在SeaObject中设计抽象方法getlmage()获取图片
     * 3)数据(状态、图片、x、y坐标)都有了，就可以开画了，每个对象都得画
     *   意味着画对象的行为为共有行为，所以在SeaObject超类中
     *   每个对象画的代码都一样，所以设计为普通方法
     *     --- 在SeaObject中设计paintImage()画对象
     * 4)画对象的方法写好了，在窗口World类中调用即可：
     *   ①先准备对象
     *   ②重写paint()方法画(不要求掌握) ---- 在paint()中调用paintmage()即可
     */

    /**
     * -- 判断对象是否活着 --
     */
    public boolean isLive() {
        return state == LIVE;
    }

    /**
     * -- 判断对象是否死了 --
     */
    public boolean isDead() {
        return state == DEAD;
    }

    /**
     * -- 判断对象是否碰撞 --
     */
    public boolean isHit(SeaObject other) {
        int x1 = this.x - other.width;
        int x2 = this.x + this.width;
        int y1 = this.y - other.height;
        int y2 = this.y + this.height;
        int x = other.x;
        int y = other.y;
        return x >= x1 && x <= x2
                &&
                y >= y1 && y <= y2;
    }

    /**
     * -- 对象死亡 -
     */
    public void goDead() {
        state = DEAD;
    }

    /**
     * -- 判断越界 --
     */
    public boolean isOutofBounds() {
        return this.x > World.WIDTH;
    }

    /**
     * -- 获取对象的图片 --
     */
    public abstract ImageIcon getImage();

    /**
     * -- 画对象 --
     */
    public void paintImage(Graphics g) {
        if (this.isLive()) {//若活着
            this.getImage().paintIcon(null, g, this.x, this.y);
        }
        /*
        如：假设this为侦察潜艇，则把侦察潜艇的照片画在(x,y)坐标上
        */
    }
}
